/*

This file is part of roomyak.

Copyright (C) 2008 Pixecur Technologies Incorporated (Esotera).
Visit Esotera at http://www.esoteras3.com
 
roomyak is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
 
roomyak is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
General Public License for more details.
 
You should have received a copy of the GNU General Public License
along with roomyak; see the file COPYING.  If not, write to 
Pixecur Technologies, 213-31 Peet Street, St. John's, NL, A1B 3W8. 
 
Linking this library statically or dynamically with other modules is
making a combined work based on this library.  Thus, the terms and
conditions of the GNU General Public License cover the whole
combination.
 
*/

package com.datasentinel.util.collections;

import java.io.Serializable;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;

public class ReadOnlyArrayList<E> implements ReadOnlyList<E>, Serializable
{
	private static final long serialVersionUID = 1L;

	private final List<E> list;

	ReadOnlyArrayList(List<E> list)
	{
		this.list = list;
	}

	@Override
	public E get(int index)
	{
		return list.get(index);
	}

	@Override
	public int indexOf(Object o)
	{
		return list.indexOf(o);
	}

	@Override
	public int lastIndexOf(Object o)
	{
		return list.lastIndexOf(o);
	}

	@Override
	public ListIterator<E> listIterator()
	{
		return new ReadOnlyListIteratorImpl<E>(list.listIterator());
	}

	@Override
	public ListIterator<E> listIterator(int index)
	{
		return new ReadOnlyListIteratorImpl<E>(list.listIterator(index));
	}

	@Override
	public ReadOnlyArrayList<E> subList(int fromIndex, int toIndex)
	{
		return new ReadOnlyArrayList<E>(list.subList(fromIndex, toIndex));
	}

	@Override
	public boolean contains(Object o)
	{
		return list.contains(o);
	}

	@Override
	public boolean containsAll(Collection<?> c)
	{
		return list.containsAll(c);
	}

	@Override
	public boolean isEmpty()
	{
		return list.isEmpty();
	}

	@Override
	public Iterator<E> iterator()
	{
		return new ReadOnlyIteratorImpl<E>(list.iterator());
	}

	@Override
	public ReadOnlyIterator<E> readOnlyIterator()
	{
		return new ReadOnlyIteratorImpl<E>(list.iterator());
	}
	
	@Override
	public int size()
	{
		return list.size();
	}

	@Override
	public Object[] toArray()
	{
		return list.toArray();
	}

	@Override
	public <T> T[] toArray(T[] a)
	{
		return list.toArray(a);
	}

	
	@Override
	public List<E> getCopyList()
	{
		try
		{
			@SuppressWarnings("unchecked")
			List<E> listCopy = (List<E>)list.getClass().newInstance();
			listCopy.addAll(list);
			return listCopy;
		}
		catch (Exception e)
		{
			e.printStackTrace();
		}
		return null;
	}
	
	@Override
	public ReadOnlyList<E> getCopy()
	{
		// TODO Auto-generated method stub
		return ReadOnlyCollections.asReadOnlyList(getCopyList());
	}

	@Override
	public String toString()
	{
		return list.toString();
	}
	
	@Override
	public boolean equals(Object obj)
	{
		if(obj == null)
		{
			return false;
		}
		
		if(!(obj instanceof ReadOnlyArrayList<?>))
		{
			return false;
		}
		
		if(obj == this)
		{
			return true;
		}
		
		int size = list.size();
		
		if(size != ((ReadOnlyArrayList<?>)obj).list.size())
		{
			return false;
		}
		
		for(int i = 0; i < size; ++i)
		{
			Object o = list.get(i);
			Object o2 = ((ReadOnlyArrayList<?>)obj).list.get(i);
			
			if((o == null && o2 != null) || (o != null && o2 == null))
			{
				return false;
			}
			
			if(o == null)
			{
				continue;
			}
			
			if(!o.equals(o2))
			{
				return false;
			}
		}
		
		return true;
	}
	
	@Override
	public E first()
	{
		return list.get(0);
	}
	
	@Override
	public E last()
	{
		return list.get(list.size() - 1);
	}
	
	@Override
	public E rvget(int index)
	{
		int actualIndex = size() - (index + 1);  
		return list.get(actualIndex);
	}
}
